﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using UniversalDataAccess;
using System.Configuration;
using UniversalDataAccess.BusinessEntities;
using System.Web.Services.Protocols;
using System.Xml;

namespace WebApplication1
{
    /// <summary>
    /// Summary description for BaseLogicService
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    // [System.Web.Script.Services.ScriptService]
    public class BaseLogicService : System.Web.Services.WebService
    {

        [WebMethod]
        public string HelloWorld()
        {
            return "Hello World";
        }

        #region Select available databases from web.config.
        [WebMethod]
        public List<string> SelectAvailableDataBases()
        {
            try
            {
                List<string> databaseNames = new List<string>();

            foreach (ConnectionStringSettings dbConnection in ConfigurationManager.ConnectionStrings)
            {
                if (  dbConnection.ProviderName == "System.Data.EntityClient")
                {
                    if (DataAccessBase.TestConnection(dbConnection.ConnectionString))
                    {
                        databaseNames.Add(dbConnection.Name);
                    } 
                }
            }
            return databaseNames;
             }
            catch (Exception ex)
            {
                throw;
            }
        }

        #endregion

        // COllects information from all of the available databases
        [WebMethod]
        public List<UniViewFictiveNodePair> SelectGroupList(TObject obj) 
        {
            List<UniViewFictiveNodePair> list = new List<UniViewFictiveNodePair>();
            List<String> dataBases = SelectAvailableDataBases();

            DataAccessBase dataAccess = null;
            foreach (String database in dataBases)
            {
                    dataAccess = new DataAccessBase(database, ConfigurationManager.ConnectionStrings[database].ConnectionString, false);
                    List<UniViewFictiveNodePair> groups = dataAccess.SelectGroupList(obj.CLASS_ID);
                    foreach (UniViewFictiveNodePair np in groups)
                    {
                        if (list.IndexOf(np) == -1)
                            list.Add(np);
                    }
            }

            return list;
        }

        #region Insert / Update /Delete TObject.

        [WebMethod]
        public void InsertTobject( TObject tobject)
        {
            try
            {
                DataAccessBase e = new DataAccessBase(tobject.DataBaseName,
                    ConfigurationManager.ConnectionStrings[tobject.DataBaseName].ConnectionString, false);

                int generated_id = -1;
                e.InsertTObject(tobject,ref  generated_id);
            }
            catch (Exception ex)
            {
                throw new Exception("Error while InsertTobject");
            }
        }

        [WebMethod]
        public void UpdateTobject( TObject tobject)
        {
            try
            {
                DataAccessBase e = new DataAccessBase(tobject.DataBaseName, 
                    ConfigurationManager.ConnectionStrings[tobject.DataBaseName].ConnectionString, false);

                e.UpdateTObject(tobject);
            }
            catch (Exception ex)
            {
                throw new Exception("Error while UpdateTobject");
            }
        }

        [WebMethod]
        public void DeleteTobject(TObject tobject)
        {
            try
            {
                DataAccessBase e = new DataAccessBase(tobject.DataBaseName, 
                    ConfigurationManager.ConnectionStrings[tobject.DataBaseName].ConnectionString, false);

                //This  will  work  if  cascad delete could  be  enabled.  But  unfortunatelly now id doesn't work.
                //e.DeleteTObject(tobject);
                //Temporary we  mark  the  object  as  deleted ext_id = "-1"
                tobject.PARENT_ID = "-1";
                e.UpdateTObject(tobject);
            }
            catch (Exception ex)
            {
                throw new Exception("Error while DeleteTobject");
            }
        }

        #endregion

        #region Select TObject lists. 

        [WebMethod]
        public TObject SelectTObject_By_DataBase_And_Id(string databaseName, int id)
        {
            try
            {
                DataAccessBase dataAccess = null;


                dataAccess = new DataAccessBase(databaseName, ConfigurationManager.ConnectionStrings[databaseName].ConnectionString, false);
                return dataAccess.SelectTObject_By_Id(id);
            }
            catch (Exception ex)
            {
                throw;
            }
        }  
        

             [WebMethod]
        public TObject SelectTObject_By_Ext_Id(string extid)
        {
            List<TObject> list = new List<TObject>();
            List<string> dataBases = SelectAvailableDataBases();

            DataAccessBase dataAccess = null;
            foreach (string database in dataBases)
            {
                try
                {
                    dataAccess = new DataAccessBase(database, ConfigurationManager.ConnectionStrings[database].ConnectionString, false);
                    TObject obj = dataAccess.SelectTObject_By_Ext_Id(extid);
                    if (obj != null) list.Add(obj);
                }
                catch (Exception ex)
                {
                    //XmlDocument doc = new XmlDocument();
                    //XmlNode node = doc.CreateNode(XmlNodeType.Element, SoapException.DetailElementName.Name,
                    //    SoapException.DetailElementName.Namespace);
                    //XmlNode child = doc.CreateNode(XmlNodeType.Element,
                    //    "ExceptionType", 
                    //    SoapException.DetailElementName.Namespace);
                    //child.InnerText = ex.GetType().ToString();
                    //node.AppendChild(child);

                    //throw new SoapException(ex.Message, 
                    //    SoapException.ServerFaultCode,
                    //    Context.Request.Url.AbsoluteUri,
                    //    node); 
                }
            }

            return list.FirstOrDefault();
        }  

        [WebMethod]
        public List<TObject> SelectTObjectListByParentId(string parentId)
        {
            List<TObject> list = new List<TObject>();
            List<string> dataBases = SelectAvailableDataBases();

            DataAccessBase dataAccess = null;
            foreach (string database in dataBases)
            {
                try
                {
                    dataAccess = new DataAccessBase(database, ConfigurationManager.ConnectionStrings[database].ConnectionString, false);
                    list.AddRange(dataAccess.SelectTObjectList_By_Parent_Id(parentId));
                }
                catch (Exception ex)
                {
                    //XmlDocument doc = new XmlDocument();
                    //XmlNode node = doc.CreateNode(XmlNodeType.Element, SoapException.DetailElementName.Name,
                    //    SoapException.DetailElementName.Namespace);
                    //XmlNode child = doc.CreateNode(XmlNodeType.Element,
                    //    "ExceptionType", 
                    //    SoapException.DetailElementName.Namespace);
                    //child.InnerText = ex.GetType().ToString();
                    //node.AppendChild(child);

                    //throw new SoapException(ex.Message, 
                    //    SoapException.ServerFaultCode,
                    //    Context.Request.Url.AbsoluteUri,
                    //    node); 
                }
            }

            return list;
        }       


        [WebMethod]
        public List<TObject> SelectTObjectList_By_Class_Id(int[] classIds)
        {
            List<TObject> list = new List<TObject>();
            List<string> dataBases = SelectAvailableDataBases();

            DataAccessBase dataAccess = null;
            foreach (string database in dataBases)
            {
                try
                {
                    dataAccess = new DataAccessBase(database, ConfigurationManager.ConnectionStrings[database].ConnectionString, false);
                    list.AddRange(dataAccess.SelectTObjectList_By_Class_Id(classIds));
                }
                catch (Exception ex)
                {
                    throw new Exception("Error while SelectTObjectList_By_Class_Id");
                }
            }

            return list;
        }
        [WebMethod]
        public List<TObject> SelectTObjectListByDataBaseName(string dataBaseName)
        {
            try
            {
                DataAccessBase e = new DataAccessBase(dataBaseName, 
                    ConfigurationManager.ConnectionStrings[dataBaseName].ConnectionString, false);

                return e.SelectTObjectsList();
            }
            catch (Exception ex)
            {
                throw new Exception("Error while SelectTObjectListByDataBaseName");
            }
        }        

        #endregion

        

        [WebMethod]
        public string SelectClassFormNameByTobjectDBandClass_Id(string dataBaseName, int class_id)
        {
            try
            {
                DataAccessBase e = new DataAccessBase(dataBaseName,
                    ConfigurationManager.ConnectionStrings[dataBaseName].ConnectionString, false);

                return e.SelectClassFormNameByTobjectDBandClass_Id(class_id);
            }
            catch (Exception ex)
            {
                throw new Exception("Error while SelectClassFormNameByTobjectDBandClass_Id");
            }
        }

        [WebMethod]
        public string SelectClassGroupNameByTobjectDBandClass_Id(string dataBaseName, int class_id)
        {
            try
            {
                DataAccessBase e = new DataAccessBase(dataBaseName,
                    ConfigurationManager.ConnectionStrings[dataBaseName].ConnectionString, false);

                return e.SelectClassGroupNameByTobjectDBandClass_Id(class_id);
            }
            catch (Exception ex)
            {
                throw new Exception("Error while SelectClassGroupNameByTobjectDBandClass_Id");
            }
        }


        [WebMethod]
        public List<InsertRule> SelectRuleInsertByClass_Id(string dataBaseName, int class_id)
        {
            try
            {
                DataAccessBase e = new DataAccessBase(dataBaseName,
                    ConfigurationManager.ConnectionStrings[dataBaseName].ConnectionString, false);

                return e.SelectRuleInsertByClass_Id(class_id);
            }
            catch (Exception ex)
            {
                throw new Exception("Error while SelectRuleInsertByClass_Id");
            }
        }

                [WebMethod]
        public List<TClass> SelectChildRuleInsertClassesByParentClass_Id(string dataBaseName, int class_id)
        {
            try
            {
                DataAccessBase e = new DataAccessBase(dataBaseName,
                    ConfigurationManager.ConnectionStrings[dataBaseName].ConnectionString, false);

                return e.SelectChildRuleInsertClassesByParentClass_Id(class_id);
            }
            catch (Exception ex)
            {
                throw new Exception("Error while SelectChildRuleInsertClassesByParentClass_Id");
            }
        }

        #region Select / Insert / Update /Delete TRuleInsert.

                [WebMethod]
                public List<InsertRule> SelectTRuleInsertListByDataBaseName(string dataBaseName)
                {
                    try
                    {
                        DataAccessBase e = new DataAccessBase(dataBaseName,
                            ConfigurationManager.ConnectionStrings[dataBaseName].ConnectionString, false);

                        return e.SelectTRuleInsertList();
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("Error while SelectTRuleInsertListByDataBaseName");
                    }
                }        

                [WebMethod]
                public void InsertTRuleInsert(InsertRule insertRule)
                {
                    try
                    {
                        DataAccessBase e = new DataAccessBase(insertRule.DataBaseName,
                            ConfigurationManager.ConnectionStrings[insertRule.DataBaseName].ConnectionString, false);

                        int generated_id = -1;
                        e.InsertTRuleInsert(insertRule, ref  generated_id);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("Error while InsertTRuleInsert");
                    }
                }

                [WebMethod]
                public void UpdateTRuleInsert(InsertRule insertRule)
                {
                    try
                    {
                        DataAccessBase e = new DataAccessBase(insertRule.DataBaseName,
                            ConfigurationManager.ConnectionStrings[insertRule.DataBaseName].ConnectionString, false);

                        e.UpdateTRuleInsert(insertRule);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("Error while UpdateTRuleInsert");
                    }
                }
           
                [WebMethod]
                public void DeleteTRuleInsert(InsertRule insertRule)
                {
                    try
                    {
                        DataAccessBase e = new DataAccessBase(insertRule.DataBaseName,
                            ConfigurationManager.ConnectionStrings[insertRule.DataBaseName].ConnectionString, false);

                        e.DeleteTRuleInsert(insertRule);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("Error while DeleteTRuleInsert");
                    }
                }

                #endregion
        
        #region Select  TClasses

                [WebMethod]
                public List<TClass> SelectTClassListByDataBaseName(string dataBaseName)
                {
                    try
                    {
                        DataAccessBase e = new DataAccessBase(dataBaseName,
                            ConfigurationManager.ConnectionStrings[dataBaseName].ConnectionString, false);

                        return e.SelectTClassList();
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("Error while SelectTClassListByDataBaseName");
                    }
                }       
        
           #endregion
        
     }
}
